package com.ztr.suanfa.hmac;

import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import java.security.NoSuchAlgorithmException;

public class HMACExample {
    /**
     * 密钥：HMAC算法使用一个密钥作为输入，该密钥与参与哈希计算的消息一起使用。密钥用于增加算法的安全性，只有知道密钥的人才能生成正确的认证码。
     * 哈希函数：HMAC算法使用一个具有抗碰撞性质的哈希函数，如SHA-1、SHA-256等，来处理消息和密钥。哈希函数将消息和密钥转换为固定长度的哈希值。
     * 内部结构：HMAC算法通过在消息和密钥上进行多次迭代的哈希计算，结合了密钥的混淆和哈希函数的强大性质，以生成最终的认证码。
     * 安全性：HMAC算法提供了保密性和完整性的保证。只有知道密钥的人才能生成正确的认证码，并且在没有密钥的情况下，无法伪造正确的认证码。
     * @param args
     */
    public static void main(String[] args) {
        String message = "z123456789";
        try {
            // 生成密钥
            SecretKey secretKey = generateSecretKey();
            // 创建HMAC-SHA256的Mac实例
            Mac mac = Mac.getInstance("HmacSHA256");
            // 初始化Mac实例，并设置密钥
            mac.init(secretKey);
            // 计算认证码
            byte[] hmac = mac.doFinal(message.getBytes());
            System.out.println("HMAC-SHA256: " + bytesToHex(hmac));
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static SecretKey generateSecretKey() throws NoSuchAlgorithmException {
        KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacSHA256");
        return keyGenerator.generateKey();
    }

    public static String bytesToHex(byte[] bytes) {
        StringBuilder hexString = new StringBuilder();
        for (byte b : bytes) {
            String hex = Integer.toHexString(0xff & b);
            if (hex.length() == 1) {
                hexString.append('0');
            }
            hexString.append(hex);
        }
        return hexString.toString();
    }
}
